package fps;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFrame;

public class Example extends JFrame implements KeyListener {
	private static final long serialVersionUID = -9174020429344694746L;

	// keys
	public boolean upPressed, downPressed, leftPressed, rightPressed;
	
	public Example(){
		super();
		this.setVisible(true);
		this.setExtendedState(JFrame.MAXIMIZED_BOTH);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.addKeyListener(this);
	}
	
	public void run() {

		final int SCREEN_SIZE = 362;
		final int HALF_SCREEN_SIZE = SCREEN_SIZE / 2;
		final int SCREEN_DISTANCE = SCREEN_SIZE;
		final int SKY_Y = 8192;

		final String S = "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u4000\u4000\ud000\ud000\ud000\u5000\u5400\u4000\u0000\u0000\u4000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u555c\ub7a9\ua9ae\u69a5\uda65\uf95b\ub5bb\u6a6d\u5eed\u5599\u5555\u5454\u0005\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\uc000\u4000\u4000\u7000\u6000\ud010\ud436\ud91a\ud7d5\ub5bf\ub767\ub679\ub559\ub6d5\u5559\u0d55\u4b6a\u4015\u4000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u4000\u4000\u4000\u4000\u4000\ud000\ua000\ud800\u7800\u9400\ufc00\ub400\ua500\u0100\u0000\u6c00\ue568\ubfe5\uaabf\uaaab\uaffb\u9abb\u9aba\u9aba\u9aba\u956a\uaaaa\ubabb\uaaaa\u9a99\uaaaa\u5555\u5555\u5665\u5655\u5ed5\u6a55\u5a56\u7559\u1557\u1955\u1990\u1590\u1994\u5994\u7654\u75f5\u57a9\u57a9\u55a5\u5555\u5559\u5599\u5599\u5565\u5766\u5766\u976a\u5955\u597d\u55a9\u5e9a\u565f\u5675\u555a\u55af\u56aa\u1565\u0005\u555c\ufff5\ubbb7\u99b6\uaab6\u5ab6\ufeb6\u5ab6\uaab6\u5ab6\ufeb6\u5ada\uaada\uaada\uaada\uaada\uffda\uaad5\u6f55\u6a55\u6f55\ubd5a\u5555\u155a\u1a95\u0540\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0005\u0015\u001d\u0015\u0015\u0029\u0055\u0055\u0000\u0000\u5555\uffff\ueebe\u6696\uaaaa\uaa55\uabff\uaa55\uaaaa\uaa55\ubbff\ua955\ubaea\ua9aa\ubaaa\uaaaa\uafff\uaaaa\u7e59\u6a59\u7e59\u5eaa\u5555\u9560\u5a90\u0100\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u6000\u5000\u0000\u0000\u700d\ud397\u5556\uaa96\uaa56\uaa96\u5a56\u9a96\u9a56\u9a96\uea96\uaa95\uaaa5\ufa95\ubaa5\u6a95\uaaa5\u5555\u5555\u6555\u6555\ued69\uaa55\u5a56\u7556\u5a64\u6690\u6690\u6650\u6550\u66e4\u6678\u5964\uf554\uad50\uad50\ua550\u5550\u5550\u6550\u6550\u9550\u9550\u9650\u9564\u5564\ud555\ud55d\u6555\u6555\u6555\u5555\ud595\u9000\u5400\u0035\u015b\u0015\u00d5\u00aa\u006a\u036a\u026b\u01ab\u01ab\u0dab\u1fea\u1aaa\u1aaf\u1a9a\u1695\u06aa\u0555\u0015\u0056\u0055\u0055\u0017\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0005\u0006\u0006\u0005\u0005\u0006\u0006\u0006\u0005\u0019\u0019\u0019\u0015\u006d\u015a\u0675\u19df\u15af\u1ff5\u5baf\u555a\u0155\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u002a\uaa7f\u556a\u0015\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ua000\ua800\uee00\uf780\ubbe0\ubae0\ue7f8\ub6f8\udbf8\u6efe\ubbfd\ueffd\ubf5d\u7dad\u1ead\u1fad\u07fd\u07d4\u0140\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u9000\u5400\u0000\u0000\u0000\ua800\ufea0\ueafa\u76aa\udbaf\u6faf\u6eff\u5bba\u6efa\u5aae\u66ab\u999a\ua666\ua955\ueaaa\u5555\u1554\u1554\u5554\u5550\u5540\u9900\u5500\ue900\ube40\uef90\uef90\udf90\u9f50\u7d00\u9400\u4000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u4000\u5400\ua900\u9b90\uaab9\u6aeb\u5555\u0000\u0000\u0000\u02aa\u0bff\u2fff\u2abf\ubfa9\u7ff6\ubff6\u7ff6\ubff6\u7ea6\uaa56\u55ae\u6abb\u6eef\u17bb\u0155\u0000\u0000\u0000\u0000\u0000\u0001\uafa9\ud69e\ua7f7\udffd\udf7d\udeed\ue7f7\uf95a\uaaa5\u5555\u9954\u6550\u9500\u5000\u4000\u0000\u0000\u0000\u0000\u4000\u4000\u4000\u4000\u5000\u9000\u5000\u9000\u6400\u9400\u6540\u97d0\u6ab5\u156b\u0016\u0001\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u002f\u001d\u005b\u01bf\u17ff\u6fff\uffff\ubffe\u7fa5\u5905\u001a\u0156\u01a9\u0199\u05a9\u0565\u05a9\u05a9\u016a\u006a\u006a\u001a\u0016\u0005\u0006\u0005\u0001\u0015\u006a\u0016\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0016\u007f\u017b\u067f\u0bd9\u1ff4\ubff8\ubfe0\uff40\ufd00\uf400\ud000\u8000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ufa00\uff80\u9940\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u008b\u02cb\u02ef\u02ef\u02ee\u03ed\u03b8\u03b8\u0ba8\u0ba0\u0be0\u07e0\u07e0\u0b80\u0b80\u0f80\u2e80\u0680\u0580\u0740\u1fd0\u2eda\u1fff\u16ef\u6bbb\u1666";
		//System.out.println("\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u4000\u4000\ud000\ud000\ud000\u5000\u5400\u4000\u0000\u0000\u4000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u555c\ub7a9\ua9ae\u69a5\uda65\uf95b\ub5bb\u6a6d\u5eed\u5599\u5555\u5454\u0005\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\uc000\u4000\u4000\u7000\u6000\ud010\ud436\ud91a\ud7d5\ub5bf\ub767\ub679\ub559\ub6d5\u5559\u0d55\u4b6a\u4015\u4000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u4000\u4000\u4000\u4000\u4000\ud000\ua000\ud800\u7800\u9400\ufc00\ub400\ua500\u0100\u0000\u6c00\ue568\ubfe5\uaabf\uaaab\uaffb\u9abb\u9aba\u9aba\u9aba\u956a\uaaaa\ubabb\uaaaa\u9a99\uaaaa\u5555\u5555\u5665\u5655\u5ed5\u6a55\u5a56\u7559\u1557\u1955\u1990\u1590\u1994\u5994\u7654\u75f5\u57a9\u57a9\u55a5\u5555\u5559\u5599\u5599\u5565\u5766\u5766\u976a\u5955\u597d\u55a9\u5e9a\u565f\u5675\u555a\u55af\u56aa\u1565\u0005\u555c\ufff5\ubbb7\u99b6\uaab6\u5ab6\ufeb6\u5ab6\uaab6\u5ab6\ufeb6\u5ada\uaada\uaada\uaada\uaada\uffda\uaad5\u6f55\u6a55\u6f55\ubd5a\u5555\u155a\u1a95\u0540\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0005\u0015\u001d\u0015\u0015\u0029\u0055\u0055\u0000\u0000\u5555\uffff\ueebe\u6696\uaaaa\uaa55\uabff\uaa55\uaaaa\uaa55\ubbff\ua955\ubaea\ua9aa\ubaaa\uaaaa\uafff\uaaaa\u7e59\u6a59\u7e59\u5eaa\u5555\u9560\u5a90\u0100\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u6000\u5000\u0000\u0000\u700d\ud397\u5556\uaa96\uaa56\uaa96\u5a56\u9a96\u9a56\u9a96\uea96\uaa95\uaaa5\ufa95\ubaa5\u6a95\uaaa5\u5555\u5555\u6555\u6555\ued69\uaa55\u5a56\u7556\u5a64\u6690\u6690\u6650\u6550\u66e4\u6678\u5964\uf554\uad50\uad50\ua550\u5550\u5550\u6550\u6550\u9550\u9550\u9650\u9564\u5564\ud555\ud55d\u6555\u6555\u6555\u5555\ud595\u9000\u5400\u0035\u015b\u0015\u00d5\u00aa\u006a\u036a\u026b\u01ab\u01ab\u0dab\u1fea\u1aaa\u1aaf\u1a9a\u1695\u06aa\u0555\u0015\u0056\u0055\u0055\u0017\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0005\u0006\u0006\u0005\u0005\u0006\u0006\u0006\u0005\u0019\u0019\u0019\u0015\u006d\u015a\u0675\u19df\u15af\u1ff5\u5baf\u555a\u0155\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u002a\uaa7f\u556a\u0015\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ua000\ua800\uee00\uf780\ubbe0\ubae0\ue7f8\ub6f8\udbf8\u6efe\ubbfd\ueffd\ubf5d\u7dad\u1ead\u1fad\u07fd\u07d4\u0140\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u9000\u5400\u0000\u0000\u0000\ua800\ufea0\ueafa\u76aa\udbaf\u6faf\u6eff\u5bba\u6efa\u5aae\u66ab\u999a\ua666\ua955\ueaaa\u5555\u1554\u1554\u5554\u5550\u5540\u9900\u5500\ue900\ube40\uef90\uef90\udf90\u9f50\u7d00\u9400\u4000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u4000\u5400\ua900\u9b90\uaab9\u6aeb\u5555\u0000\u0000\u0000\u02aa\u0bff\u2fff\u2abf\ubfa9\u7ff6\ubff6\u7ff6\ubff6\u7ea6\uaa56\u55ae\u6abb\u6eef\u17bb\u0155\u0000\u0000\u0000\u0000\u0000\u0001\uafa9\ud69e\ua7f7\udffd\udf7d\udeed\ue7f7\uf95a\uaaa5\u5555\u9954\u6550\u9500\u5000\u4000\u0000\u0000\u0000\u0000\u4000\u4000\u4000\u4000\u5000\u9000\u5000\u9000\u6400\u9400\u6540\u97d0\u6ab5\u156b\u0016\u0001\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u002f\u001d\u005b\u01bf\u17ff\u6fff\uffff\ubffe\u7fa5\u5905\u001a\u0156\u01a9\u0199\u05a9\u0565\u05a9\u05a9\u016a\u006a\u006a\u001a\u0016\u0005\u0006\u0005\u0001\u0015\u006a\u0016\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0016\u007f\u017b\u067f\u0bd9\u1ff4\ubff8\ubfe0\uff40\ufd00\uf400\ud000\u8000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\ufa00\uff80\u9940\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u008b\u02cb\u02ef\u02ef\u02ee\u03ed\u03b8\u03b8\u0ba8\u0ba0\u0be0\u07e0\u07e0\u0b80\u0b80\u0f80\u2e80\u0680\u0580\u0740\u1fd0\u2eda\u1fff\u16ef\u6bbb\u1666");
		int i;
		int j;
		int k;
		int x;
		int y;
		int z;
		float xo = 0;
		float yo = 0;
		float zo = 0;
		float yaw = 0;

		float yawCos = 0;
		float yawSin = 0;
		
		BufferedImage image = new BufferedImage(362, 362, 1);
		BufferedImage image2 = new BufferedImage(512, 512, 1);
		Graphics2D g = (Graphics2D)image.getGraphics();
		Graphics2D g2 = (Graphics2D)image2.getGraphics();
		Graphics2D g3 = null;

		int[] pixels = new int[362];
		int[] xPoints = new int[4];
		int[] yPoints = new int[4];

		Random random = new Random();

		int[][] floorTexture = new int[256][256];
		int[][] skyTexture = new int[256][256];
		int[][] scaledSprites = new int[4096][9];

		BufferedImage[] sprites = new BufferedImage[2];

		Color[] firePalette = new Color[32];

		for(i = 0; i < 32; i++) {
			firePalette[i] = new Color(255, 255, 255, 255);
		}

		// decompress sprites
		for(k = 0; k < 2; k++) {
			int width = 8;
			int height = 55;
			if (k == 1) {
				width = 7;
				height = 64;
			}
			sprites[k] = new BufferedImage(width << 3, height, 2);
			for(x = 0; x < width; x++) {
				for(y = 0; y < height; y++) {
					for(i = 0; i < 8; i++) {
						j = (S.charAt((k == 0 ? 0 : 440) + height * x + y) >> (i << 1)) & 3;
						pixels[i] = j == 0 ? 0 : 0xFF000000
								| (j == 1 ? 0 : j == 2 ? 0x7F7F7F : 0xBFBFBF);
					}
					sprites[k].setRGB(x << 3, y, 8, 1, pixels, 0, 8);
				}
			}
		}

		// generate floor texture    
		for(y = 0; y < 256; y++) {
			for(x = 0; x < 256; x++) {
				floorTexture[y][x] = 128;
			}
		}
		for(z = 0; z < 8; z++) {
			for(y = 0; y < 256; y++) {
				for(x = 0; x < 256; x++) {
					floorTexture[y][x] += random.nextInt(1 << (8 - (z >> 2)))
							- (1 << (7 - (z >> 2)));
					if (floorTexture[y][x] < 0) {
						floorTexture[y][x] = 0;
					} else if (floorTexture[y][x] > 255) {
						floorTexture[y][x] = 255;
					}
				}
			}
			for(y = 0; y < 256; y++) {
				for(x = 0; x < 256; x++) {
					k = 0;
					for(i = -1; i <= 1; i++) {
						for(j = -1; j <= 1; j++) {
							k += floorTexture[(y + i) & 0xFF][(x + j) & 0xFF];
						}
					}
					floorTexture[y][x] = k / 9;
				}
			}
		}
		for(y = 0; y < 256; y++) {
			for(x = 0; x < 256; x++) {
				i = floorTexture[y][x];
				floorTexture[y][x] = ((0xF7 + (0x9D - 0xF7) * i / 255) << 16)
						| ((0xF8 + (0xA4 - 0xF8) * i / 255) << 8)
						| (0xFD + (0xD8 - 0xFD) * i / 255);
				skyTexture[y][x] = ((0x84 + (0xBE - 0x84) * i / 255) << 16)
						| ((0xB5 + (0xDE - 0xB5) * i / 255) << 8)
						| (0xF7 + (0xF3 - 0xF7) * i / 255);
			}
		}

		long nextFrameStartTime = System.nanoTime();
		while(true) {

			do {
				nextFrameStartTime += 16666667;

				// -- update starts ----------------------------------------------------

				yawCos = (float)Math.cos(yaw);
				yawSin = (float)Math.sin(yaw);
				// player moves forward
				if (upPressed){ 
					xo += 100 * yawSin;
					zo -= 100 * yawCos;
				}
				
				

				// player controls yaw
				if (leftPressed) {
					yaw -= .01;
				} else if (rightPressed) {
					yaw += .01;
				}
					
				
				// -- update ends ------------------------------------------------------

			} while(nextFrameStartTime < System.nanoTime());

			// -- render starts ------------------------------------------------------

			// draw ground and sky
			for(i = 0; i < 362; i++) { // rows

				// compute normalized ray in direction of scanline
				float ry = HALF_SCREEN_SIZE - i;
				float rz = -SCREEN_DISTANCE;
				float mag = (float)Math.sqrt(ry * ry + rz * rz);
				ry /= mag;
				rz /= mag;

				for(k = 0; k < 2; k++) {
					float t = (SKY_Y * k - yo) / ry;
					int[][] texture = k == 0 ? floorTexture : skyTexture;
					int textureScale = k == 0 ? 4 : 8;
					if (t > 0) {
						// compute scale and left of scanline on floor
						float scale = t / SCREEN_DISTANCE;
						float floorX = -scale * HALF_SCREEN_SIZE;
						float floorZ = rz * t;

						// rotate the scanline based on yaw angle
						float fx = floorX * yawCos - floorZ * yawSin;
						float fz = floorX * yawSin + floorZ * yawCos;
						float dfx = scale * yawCos;
						float dfz = scale * yawSin;

						// scanning across row
						for(j = 0; j < 362; j++) {
							pixels[j] = texture[((int)(zo + fz) >> textureScale) & 0xFF]
									[((int)(xo + fx) >> textureScale) & 0xFF];

							fx += dfx;
							fz += dfz;
						}

						image.setRGB(0, i, SCREEN_SIZE, 1, pixels, 0, SCREEN_SIZE);
					}
				}
			}
			g2.drawImage(image, 0, 0, 724, 724, null);
			//this.repaint();

			// -- render ends --------------------------------------------------------

			// show the hidden buffer
			if (g3 == null) {
				g3 = (Graphics2D)getGraphics();
				requestFocus();
			} else {
				g3.drawImage(image2, 0, 0, null);
			}

			// burn off extra cycles
			while(nextFrameStartTime - System.nanoTime() > 0) {
				Thread.yield();
			}
		}
	}

	@Override
	public void keyTyped(KeyEvent ke) {
		
		
	}

	@Override
	public void keyPressed(KeyEvent ke) {
		if (ke.getKeyCode() == KeyEvent.VK_UP) {
			upPressed = true;
		}
		if (ke.getKeyCode() == KeyEvent.VK_DOWN) {
			downPressed = true;
		}
		if (ke.getKeyCode() == KeyEvent.VK_LEFT) {
			leftPressed = true;
		}
		if (ke.getKeyCode() == KeyEvent.VK_RIGHT) {
			rightPressed = true;
		}
		
	}

	@Override
	public void keyReleased(KeyEvent ke) {
		if (ke.getKeyCode() == KeyEvent.VK_UP) {
			upPressed = false;
		}
		if (ke.getKeyCode() == KeyEvent.VK_DOWN) {
			downPressed = false;
		}
		if (ke.getKeyCode() == KeyEvent.VK_LEFT) {
			leftPressed = false;
		}
		if (ke.getKeyCode() == KeyEvent.VK_RIGHT) {
			rightPressed = false;
		}
		
	}
	
	public static void main(String[] args){
		new Example().run();
	}
}
